package com.smartwebx.fr.service.ckeditor;

import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.smartwebx.fr.bean.SimpleUseArgConf;
import com.smartwebx.fr.bean.SwapOrderEle;
import com.smartwebx.fr.bean.mysql.PageUseArg;
import com.smartwebx.fr.dao.mysql.PageUseArgMapper;
import com.smartwebx.fr.service.StoredProcService;
import com.smartwebx.fr.util.CurrLocalSeIdUseParam;
import com.smartwebx.fr.util.InitLoadingSites;
import com.smartwebx.fr.util.USE_TYPE;

/**
 * 用户参数 service
 * 
 * @author XX
 * 
 */
@Service
@Transactional
public class UseArgConfService {
	@Autowired
	private PageUseArgMapper useArgConfDao;
	@Autowired
	private StoredProcService storedProcService;

	private ObjectMapper mapper = new ObjectMapper();

	public void updateShowValueById(String sessionId, List<PageUseArg> objs) {
		List<PageUseArg> cachePageuseArgs = Lists.newArrayList();
		for (PageUseArg obj : objs) {
			PageUseArg dbUseArgConf = useArgConfDao.selectByPrimaryKey(obj
					.getId());
			dbUseArgConf.setShowValue(obj.getShowValue());
			// 只在数据库保存不是脚本的值
			if (BooleanUtils.isNotTrue(dbUseArgConf.getIsScript())) {
				useArgConfDao.updateByPrimaryKeySelective(dbUseArgConf);
			}
			cachePageuseArgs.add(dbUseArgConf);
		}
		// CurrLocalSeIdUseParam.putUseParams(sessionId, cachePageuseArgs);
	}

	/**
	 * 保存
	 * 
	 * @param beanList
	 * @throws IOException
	 */

	public String saveOrUpdate(String data) throws IOException {
		String uaId = null;

		PageUseArg uac = mapper.readValue(data, PageUseArg.class);

		String argTypeStr = uac.getArgType();
		USE_TYPE argType = Enum.valueOf(USE_TYPE.class, argTypeStr);
		if (uac.getId() == null) {// 新增
			Integer max = useArgConfDao.getMaxOrderId(uac.getPageId());
			if (max == null) {
				max = 0;
			}
			// 根据数据库中的已知最大值，得到索引值
			uac.setOrderId(max + 1);

			// 修改时间
			uac.setLastTime(new Date());

			uaId = UUID.randomUUID().toString();
			uac.setId(uaId);

			if (argType == USE_TYPE.DOWNLIST || argType == USE_TYPE.DAY
					|| argType == USE_TYPE.TEXT || argType == USE_TYPE.DATETIME) {
				if (argType == USE_TYPE.DOWNLIST) {
					downListHandle(uac);
				} else {
					uac.setShowValue(uac.getArgValue());
				}
			}
			useArgConfDao.insertSelective(uac);
		} else {
			// 修改时间
			uac.setLastTime(new Date());
			if (argType == USE_TYPE.DOWNLIST || argType == USE_TYPE.DAY
					|| argType == USE_TYPE.TEXT || argType == USE_TYPE.DATETIME) {
				if (argType == USE_TYPE.DOWNLIST) {
					downListHandle(uac);
				} else {
					if (BooleanUtils.isNotTrue(uac.getIsScript())) {
						uac.setShowValue(uac.getArgValue());
					}
				}
			} else if (argType == USE_TYPE.SINGLESITE
					|| argType == USE_TYPE.SITEGROUP) {
				uac.setShowValue("");
				uac.setArgValue("");
			}
			useArgConfDao.updateByPrimaryKeySelective(uac);
			uaId = uac.getId();
		}
		return uaId;
	}

	private void downListHandle(PageUseArg uac) throws JsonProcessingException {
		Boolean isSql = uac.getIsSql();
		String argVal = uac.getArgValue();
		String showValue = null;
		if (isSql) {
			String querySql = argVal;
			List<SimpleUseArgConf> useArgs = Lists.newArrayList();
			List<List<String>> results = storedProcService
					.getResultBySqlAndPageParam(querySql, useArgs, "table",
							false);
			List<String> lineList = Lists.newArrayList();
			Map<String, String> selectItem = null;
			for (List<String> line : results) {
				String id = line.get(0);
				String text = line.get(1);
				lineList.add(id + "->" + text);
				if (selectItem == null) {
					selectItem = ImmutableMap.of("k", id, "v", text);
				}
			}
			showValue = mapper.writeValueAsString(new DownListShowValue(Joiner
					.on(';').join(lineList), selectItem));
		} else {
			// 设置默认值
			String defItemStr = Iterables
					.get(Splitter.on(";").split(argVal), 0);
			String[] defItemKV = StringUtils.split(defItemStr, "->");
			showValue = mapper.writeValueAsString(new DownListShowValue(argVal,
					ImmutableMap.of("k", defItemKV[0], "v", defItemKV[1])));
		}
		uac.setShowValue(showValue);
	}

	/**
	 * 根据pageId返回List
	 * 
	 * @param uiId
	 * @return
	 */
	public List<PageUseArg> getListByPageId(Integer pageId) {
		List<PageUseArg> params = useArgConfDao.getPageUseArgByPageId(pageId);
		return params;
	}

	public List<SimpleUseArgConf> getSimpleUseArgConfs(Integer pageId)
			throws Exception {
		List<PageUseArg> useArgs = CurrLocalSeIdUseParam.getPageUseArgs();

		if (useArgs.isEmpty()) {
			return Lists.newArrayList();
		}

		List<SimpleUseArgConf> simpleArgs = Lists.newArrayList();
		for (PageUseArg useArg : useArgs) {
			SimpleUseArgConf simpleArg = new SimpleUseArgConf();
			simpleArg.setId(useArg.getId());
			String name = useArg.getArgName();
			simpleArg.setName(name);
			String showValue = useArg.getShowValue();
			simpleArg.setVal(showValue);

			String argType = useArg.getArgType();
			// 取得单站、站群 对应的站名
			if (!Strings.isNullOrEmpty(showValue) && "SINGLESITE".equals(argType) || "SITEGROUP".equals(argType)) {
				String siteNames = findSiteNameById(showValue);
				SimpleUseArgConf otherSimpleArg = new SimpleUseArgConf();
				otherSimpleArg.setName(name + "_V");
				otherSimpleArg.setVal(siteNames);
				simpleArgs.add(otherSimpleArg);
			} else if ("DOWNLIST".equals(argType)) {
				DownListShowValue downListShowVal = mapper.readValue(showValue,
						DownListShowValue.class);
				Map<String, String> selectItem = downListShowVal
						.getSelectItem();
				String id = selectItem.get("k");
				String text = selectItem.get("v");
				simpleArg.setVal(id);

				SimpleUseArgConf otherSimpleArg = new SimpleUseArgConf();
				otherSimpleArg.setName(name + "_V");
				otherSimpleArg.setVal(text);
				simpleArgs.add(otherSimpleArg);
			} else if ("DAY".equals(argType)) {
				try {
					Date date = DateUtils.parseDate(showValue, "yyyy-MM-dd");
					String chisDateFrm = DateFormatUtils.format(date,
							"yyyy年MM月dd日");
					SimpleUseArgConf otherSimpleArg = new SimpleUseArgConf();
					otherSimpleArg.setName(name + "_V");
					otherSimpleArg.setVal(chisDateFrm);
					simpleArgs.add(otherSimpleArg);
				} catch (Exception e) {
					
				}
			}
			simpleArgs.add(simpleArg);
		}
		return simpleArgs;
	}

	public String findSiteNameById(String ids) {
		Map<String, String> allSites = InitLoadingSites.getAllSites();
		List<String> names = Lists.newArrayList();
		for (String id : StringUtils.split(ids, ',')) {
			String val = allSites.get(id);
			if (val != null)
				names.add(val);
		}
		return Joiner.on('、').join(names);
	}

	/**
	 * 删除并更新 orderId 值
	 * 
	 * @param id
	 */
	public void deleteById(String id) {
		// 获得要删除的实例
		PageUseArg delUac = useArgConfDao.selectByPrimaryKey(id);
		useArgConfDao.deleteByPrimaryKey(id);

		// 获得删除实例所属的 pageId
		Integer pageId = delUac.getPageId();
		List<PageUseArg> uacList = useArgConfDao.getPageUseArgByPageId(pageId);

		for (Integer i = 0; i < uacList.size(); i++) {
			PageUseArg uac = uacList.get(i);
			uac.setOrderId(i);
		}
	}

	public void swapOrder(String data) throws JsonParseException,
			JsonMappingException, IOException {
		mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
				false);
		List<SwapOrderEle> swapOList = mapper.readValue(data,
				new TypeReference<List<SwapOrderEle>>() {
				});
		for (SwapOrderEle obj : swapOList) {
			useArgConfDao.updateOrder(obj.getEleId(), obj.getOrder());
		}
	}

}

class DownListShowValue {
	private String lines;
	private Map<String, String> selectItem;

	public DownListShowValue(String lines, Map<String, String> selectItem) {
		super();
		this.lines = lines;
		this.selectItem = selectItem;
	}

	public DownListShowValue() {
	}

	public String getLines() {
		return lines;
	}

	public void setLines(String lines) {
		this.lines = lines;
	}

	public Map<String, String> getSelectItem() {
		return selectItem;
	}

	public void setSelectItem(Map<String, String> selectItem) {
		this.selectItem = selectItem;
	}
}
